<template>
  <div class="chart-wrapper" :class="size">
    <div class="chart-title" @click="toPage()"><span>{{ data && data.name }}</span></div>
    <div :id="chartId" class="chart"></div>
  </div>
</template>

<script>
import { option, xAxis, yAxis } from '@/constants/chartOptions'

export default {
  name: 'CommonChart',
  props: ['chartType', 'size', 'data'],
  data () {
    return {
      chartTypes: ['pie', 'line', 'bar'],
      chartId: 'chart-' + Math.floor(Math.random() * 1000000000),
      colors: {
        normal: ['#25a9e1', '#e16400', '#46e04d'],
        emphasis: ['#25a9e1', '#e16400', '#46e04d']
      },
      option: JSON.parse(JSON.stringify(option)),
      xAxis: JSON.parse(JSON.stringify(xAxis)),
      yAxis: JSON.parse(JSON.stringify(yAxis)),
      cubeColors: [
        {
          left: ['rgba(0,255,186,1)', 'rgba(28,192,149,0.88)'],
          right: ['rgba(99,211,181,0.75)', 'rgba(95,187,162,0.84)'],
          top: ['rgba(50,189,151,0.91)', 'rgba(70,217,178,0.85)']
        }
      ]
    }
  },
  mounted () {
    const self = this
    setTimeout(() => {
      if (this.chartTypes.includes(this.chartType)) {
        self.draw()
      }
    }, 1000)
  },
  methods: {
    draw () {
      const CubeLeft = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0
        },
        buildPath: function (ctx, shape) {
          // 会canvas的应该都能看得懂，shape是从custom传入的
          const xAxisPoint = shape.xAxisPoint
          const c0 = [shape.x + 3, shape.y]
          const c1 = [shape.x - 11, shape.y - 3]
          const c2 = [xAxisPoint[0] - 11, xAxisPoint[1] - 6]
          const c3 = [xAxisPoint[0] + 3, xAxisPoint[1]]
          ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath()
        }
      })
      // 绘制右侧面
      const CubeRight = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0
        },
        buildPath: function (ctx, shape) {
          const xAxisPoint = shape.xAxisPoint
          const c1 = [shape.x + 3, shape.y]
          const c2 = [xAxisPoint[0] + 3, xAxisPoint[1]]
          const c3 = [xAxisPoint[0] + 12, xAxisPoint[1] - 7]
          const c4 = [shape.x + 12, shape.y - 7]
          ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
        }
      })
      // 绘制顶面
      const CubeTop = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0
        },
        buildPath: function (ctx, shape) {
          const c1 = [shape.x + 3, shape.y]
          const c2 = [shape.x + 12, shape.y - 7] // 右点
          const c3 = [shape.x - 2, shape.y - 10]
          const c4 = [shape.x - 11, shape.y - 3]
          ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
        }
      })
      // 注册三个面图形
      this.$echarts.graphic.registerShape('CubeLeft', CubeLeft)
      this.$echarts.graphic.registerShape('CubeRight', CubeRight)
      this.$echarts.graphic.registerShape('CubeTop', CubeTop)
      if (this.data.series) {
        const myChart = this.$echarts.init(document.getElementById(this.chartId))
        const option = this.option
        if (['bar', 'line'].includes(this.chartType)) {
          if (this.data.xAxis) {
            option.xAxis = this.data.xAxis.map(x => {
              return Object.assign(this.xAxis, x)
            })
          } else {
            option.yAxis = this.yAxis
          }
          if (this.data.yAxis) {
            option.yAxis = this.data.yAxis.map(y => {
              return Object.assign(this.yAxis, y)
            })
          } else {
            option.yAxis = this.yAxis
          }
        }
        if (option.legend && this.data.legend) {
          option.legend.data = this.data.legend
        }
        if (this.data.top && option.grid) {
          option.grid.top = this.data.top
        }
        option.title.text = this.data.title
        if (this.data.y) {
          option.title.y = this.data.y
        }
        if (this.data.ly) {
          option.legend.y = this.data.ly
        }
        if (this.data.titleOption) {
          option.title = Object.assign(option.title, this.data.titleOption)
        }
        option.series = this.data.series
        option.series.forEach((ele, index) => {
          ele.type = this.chartType === 'bar' ? 'custom' : this.chartType
          if (ele.type === 'custom') {
            ele.renderItem = (params, api) => {
              const location = api.coord([api.value(0), api.value(1)])
              return {
                type: 'group',
                children: [{
                  type: 'CubeLeft',
                  shape: {
                    api,
                    xValue: api.value(0),
                    yValue: api.value(1),
                    x: location[0],
                    y: location[1],
                    xAxisPoint: api.coord([api.value(0), 0])
                  },
                  style: {
                    fill: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                      {
                        offset: 0,
                        color: this.cubeColors[params.dataIndex % this.cubeColors.length].left[0]
                      },
                      {
                        offset: 1,
                        color: this.cubeColors[params.dataIndex % this.cubeColors.length].left[1]
                      }
                    ])
                  }
                },
                {
                  type: 'CubeRight',
                  shape: {
                    api,
                    xValue: api.value(0),
                    yValue: api.value(1),
                    x: location[0],
                    y: location[1],
                    xAxisPoint: api.coord([api.value(0), 0])
                  },
                  style: {
                    fill: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                      {
                        offset: 0,
                        color: this.cubeColors[params.dataIndex % this.cubeColors.length].right[0]
                      },
                      {
                        offset: 1,
                        color: this.cubeColors[params.dataIndex % this.cubeColors.length].right[1]
                      }
                    ])
                  }
                },
                {
                  type: 'CubeTop',
                  shape: {
                    api,
                    xValue: api.value(0),
                    yValue: api.value(1),
                    x: location[0],
                    y: location[1],
                    xAxisPoint: api.coord([api.value(0), 0])
                  },
                  style: {
                    fill: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
                      {
                        offset: 0,
                        color: this.cubeColors[params.dataIndex % this.cubeColors.length].top[0]
                      },
                      {
                        offset: 1,
                        color: this.cubeColors[params.dataIndex % this.cubeColors.length].top[1]
                      }
                    ])
                  }
                }]
              }
            }
          }
          ele.itemStyle = {
            normal: {
              color: this.colors.normal[index]
            },
            emphasis: {
              color: this.colors.emphasis[index]
            }
          }
        })

        option.series.push({
          type: 'bar',
          label: {
            normal: {
              show: true,
              position: 'top',
              fontSize: 10,
              color: '#fff',
              offset: [2, -12]
            }
          },
          itemStyle: {
            color: 'transparent'
          },
          tooltip: {
          },
          data: option.series[0].data
        })
        myChart.setOption(option)
      }
    },
    toPage () {
      if (this.data && this.data.routeName) {
        this.$router.replace({
          name: this.data.routeName,
          query: this.data.query
        })
      }
    }
  },
  beforeDestroy () {
    const chart = document.getElementById(this.chartId)
    if (chart) {
      const parent = chart.parentNode
      if (parent) {
        parent.removeChild(chart)
      }
    }
  }
}
</script>

<style scoped lang="scss">

</style>
